home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGSCAL / TURBOK50.LZH / SOURCE.ARC / MENUTTT5.PAS < prev    next >
Pascal/Delphi Source File  |  1989-06-02  |  25KB  |  637 lines

  1. {--------------------------------------------------------------------------}
  2. {                         TechnoJock's Turbo Toolkit                       }
  3. {                                                                          }
  4. {                              Version   5.01a                             }
  5. {                                                                          }
  6. {                                                                          }
  7. {              Copyright 1986, 1989 TechnoJock Software, Inc.              }
  8. {                           All Rights Reserved                            }
  9. {                          Restricted by License                           }
  10. {--------------------------------------------------------------------------}
  11.  
  12.                      {--------------------------------}
  13.                      {       Unit:  MenuTTT5          }
  14.                      {--------------------------------}
  15.  
  16.  
  17. {History:     2/13/89       Mod 5.00a changed Y2 calculation in proc
  18.                             Determine_Y_Dimensions
  19.                      5.01a  Removed refrences to VER50 and added DEBUG
  20.                             compiler directive 
  21. }
  22.  
  23. {$S-,R-,V-}
  24. {$IFNDEF DEBUG}
  25. {$D-}
  26. {$ENDIF}
  27.  
  28. Unit MenuTTT5;
  29.  
  30. INTERFACE
  31.  
  32. Uses CRT, FastTTT5, DOS, WinTTT5, KeyTTT5, StrnTTT5;
  33.  
  34. const
  35.    Max_Choices = 30;
  36.    MenuStrLength = 40;     {make longer if necessary}
  37. type
  38. {$IFNDEF VER40}
  39.    Menu_Hook = Procedure(var Ch:char; Choice:integer; var Ecode:integer);
  40. {$ENDIF}
  41.    Menu_record = record
  42.                   Heading1     : string[MenuStrLength];   { '' for no heading}
  43.                   Heading2     : string[MenuStrLength];
  44.                   Topic        : array[1..Max_Choices] of string[MenuStrLength];
  45.                   TotalPicks   : integer;
  46.                   PicksPerLine : byte;
  47.                   AddPrefix    : byte;                    {0 no, 1 No.'s, 2 Lets}
  48.                   TopLeftXY    : array[1..2] of byte;     {X,Y}
  49.                   Boxtype      : byte;                    {0,1,2,3, >3}
  50.                   Colors       : array[1..5] of byte;     {HF,HB,LF,LB,Box}
  51.                   Margins      : byte;
  52.                   AllowEsc     : boolean;                 {true if Esc will exit}
  53.                   {$IFNDEF VER40}
  54.                   Hook         : Menu_hook;
  55.                   {$ENDIF}
  56.                 end;
  57. {$IFDEF VER40}
  58. Var
  59.   M_UserHook : Pointer;
  60. {$ENDIF}
  61. Procedure No_Hook(var Ch:char; Choice:integer; var Ecode : integer);
  62. Procedure Menu_Set(var M : Menu_record);
  63. Procedure DisplayMenu(MenuDef: Menu_record;
  64.                       Window:Boolean;
  65.                       var Choice,Errorcode : integer);
  66.  
  67. IMPLEMENTATION
  68.  
  69. {$IFDEF VER40}
  70.    Procedure Call_Hook(var Ch:char; Choice:integer; var Ecode:integer);
  71.           Inline($FF/$1E/M_UserHook);
  72. {$ENDIF}
  73.  
  74. {$F+}
  75.  Procedure No_Hook(var Ch:char; Choice:integer; var Ecode : integer);
  76.  {}
  77.  begin
  78.  end; {of proc No_Hook}
  79. {$F-}
  80.  
  81.  Procedure Menu_Set(var M : Menu_record);
  82.  {}
  83.  begin
  84.      with M do
  85.      begin
  86.          Heading1     := '';
  87.          Heading2     := '';
  88.          Topic[1]     := '';
  89.          TotalPicks   := 0;
  90.          PicksPerLine := 1;
  91.          AddPrefix    := 1;
  92.          TopLeftXY[1] := 0;
  93.          TopLeftXY[2] := 0;
  94.          Boxtype      := 5;
  95.          If BaseOfScreen = $B800 then
  96.          begin
  97.              Colors[1]    := white;
  98.              Colors[2]    := red;
  99.              Colors[3]    := lightgray;
  100.              Colors[4]    := blue;;
  101.              Colors[5]    := lightred;
  102.          end
  103.          else
  104.          begin
  105.              Colors[1]    := white;
  106.              Colors[2]    := black;
  107.              Colors[3]    := lightgray;
  108.              Colors[4]    := black;
  109.              Colors[5]    := white;
  110.          end;
  111.          Margins      := 5;
  112.          AllowEsc     := true;
  113.          {$IFNDEF VER40}
  114.                  Hook         := NO_Hook;
  115.          {$ELSE}
  116.                  M_UserHook := Nil;
  117.          {$ENDIF}
  118.      end;
  119.  end; {of proc Menu_Set}
  120.  
  121.  Procedure MenuError(Code:byte);    {fatal error -- msg and halt}
  122.  var Message:string;
  123.  begin
  124.      {Clrscr;}
  125.      Case Code of
  126.      1 : Message := 'Fatal Error 1: Too Many Picks to display. Change PicksPerLine';
  127.      else Message := 'Aborting';
  128.      end; {case}
  129.      WriteAT(1,12,black,lightgray,Message);
  130.      Repeat Until keypressed;
  131.      Halt;
  132.  end;    {proc MenuError}
  133.  
  134. Procedure DisplayMenu(MenuDef: Menu_record;
  135.                       Window:Boolean;
  136.                       var Choice,Errorcode : integer);
  137. Const
  138. Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  139. Numbers  = '123456789';
  140. var
  141. I,J,X2,Y2,heading_Lines : integer;
  142. TextWidth : byte;
  143.  
  144.  
  145.     Function Int_to_Str(Number:Integer):string;
  146.     var Temp : string;
  147.     begin
  148.        Str(Number,temp);
  149.        Int_to_Str := temp;
  150.     end;
  151.  
  152.     Function  Str_to_Int(Str:string):integer;
  153.     var temp,code : integer;
  154.     begin
  155.         If length(Str) = 0 then
  156.            Str_to_Int := 0
  157.         else
  158.         begin
  159.             val(Str,temp,code);
  160.             if code = 0 then
  161.                Str_to_Int := temp
  162.             else
  163.                Str_to_Int := 0;
  164.         end;
  165.     end;
  166.  
  167.    Procedure GetDimensions;
  168.    var Fullwidth,MaxWidth: integer;
  169.  
  170.      Procedure Validate_Prefix;                          { 0   no prefix  }
  171.      begin                                               { 1   numbers prefix}
  172.          with MenuDef do                                 { 2   letters prefix}
  173.          begin                                           { 3   function key prefix}
  174.              If PicksPerLine < 1 then PicksPerLine := 1; { 4   capital letter selection}
  175.              If (TotalPicks = 10) and (AddPrefix = 1) then
  176.                 AddPrefix := 3;
  177.              If (TotalPicks > 10) and (AddPrefix in [1,3]) then
  178.                 AddPrefix := 2;
  179.              If (Addprefix > 4) or (TotalPicks > 26) or (Addprefix < 0) then
  180.                 Addprefix := 0;
  181.              end; {do}
  182.      end; {Validate_Prefix}
  183.  
  184.    Procedure Add_Prefix;
  185.    var I : integer;
  186.    begin
  187.        With MenuDef do
  188.        begin
  189.            Case AddPrefix of
  190.            1 : for I := 1 to TotalPicks do
  191.                    Topic[I] := int_to_str(I) + ' ' + Topic[I];
  192.            2 : for I := 1 to TotalPicks do
  193.                    Topic[I] := Copy(Alphabet,I,1) + ' ' + Topic[I];
  194.            3 : If TotalPicks < 10 then
  195.                   for I := 1 to TotalPicks do
  196.                       Topic[I] := 'F'+Int_to_Str(I) + ' ' + Topic[I]
  197.                else
  198.                begin                           {add extra space for F10 }
  199.                    for I := 1 to 9 do
  200.                        Topic[I] := 'F'+Int_to_Str(I) + '  ' + Topic[I];
  201.                    Topic[10] := 'F10 '+ Topic[10];
  202.                end;
  203.            end; {case}
  204.        end;  {do}
  205.    end;  {proc Add_Prefix}
  206.  
  207.      Procedure Find_Longest_Topic;
  208.      var
  209.        I,J: integer;
  210.      begin
  211.          with MenuDef do
  212.          begin
  213.              Textwidth := 0;
  214.              For I := 1 to TotalPicks do
  215.                  If length(Topic[I]) > TextWidth then
  216.                     Textwidth := length(Topic[I]);         {find the longest text}
  217.          end;  {with}
  218.      end;   {Proc Find_Widest_Line}
  219.  
  220.    Procedure Adjust_Text_Width(Len:integer);
  221.    var I,J : integer;
  222.    begin
  223.        With MenuDef do
  224.        begin
  225.            For I := 1 to TotalPicks do
  226.                If length(Topic[I]) > Len then         {reduce it}
  227.                   Delete(Topic[I],succ(Len),length(Topic[I]) - Len)
  228.                else                                  {expand it}
  229.                   For J := length(Topic[I]) + 1 to Textwidth do
  230.                       Topic[I] :=  Topic[I] + ' ';
  231.        end; {do}
  232.    end;
  233.  
  234.    Procedure Determine_MaxWidth;
  235.    {findout the max internal menu space - MaxWidth}
  236.    begin
  237.        with MenuDef do
  238.        begin
  239.            If margins < 0 then Margins := 0;
  240.            If not (BoxType in [0..9]) then
  241.               BoxType := 0;
  242.            MaxWidth := 80 - 2*Margins - 1; {-1 for arrow symbol to left of pick}
  243.            Case BoxType of
  244.            1..4 : MaxWidth := MaxWidth - 2;     {box sides}
  245.            5    : MaxWidth := pred(MaxWidth);    {box shadow}
  246.            6..9 : MaxWidth := MaxWidth - 3;     {box sides and shadow}
  247.            end;
  248.        end; {with}
  249.    end;
  250.  
  251.    Procedure Validate_PicksPerLine;
  252.    begin
  253.        With MenuDef do
  254.        begin
  255.            If succ(TextWidth)*PicksPerLine <= MaxWidth then
  256.               exit;  {no adjustment necessary, everything fits}
  257.            If (TextWidth-2)*PicksPerLine <= Maxwidth  then
  258.                TextWidth := pred(MaxWidth div PicksperLine)
  259.            else
  260.            begin
  261.                While succ(TextWidth)*PicksPerLine > MaxWidth do
  262.                      PicksPerLine := pred(PicksPerLine);
  263.                If PicksPerLine = 0 then
  264.                begin
  265.                    TextWidth := pred(MaxWidth);
  266.                    PicksPerLine := 1;
  267.                end;
  268.            end;
  269.        end; {with}
  270.    end;  {Proc Validate_PicksPerLine}
  271.  
  272.    Procedure Determine_X_Dimensions;
  273.    {Checks to see if the menu will fit, if it won't it changes something!}
  274.    begin
  275.        With MenuDef do
  276.        begin
  277.            Fullwidth := succ(Textwidth)*PicksPerLine + 2*Margins;
  278.            Case BoxType of
  279.            1..4 : FullWidth := FullWidth + 2;     {box sides}
  280.            5    : FullWidth := succ(FullWidth);   {box shadow}
  281.            6..9 : FullWidth := FullWidth + 3;     {box sides and shadow}
  282.            end; {Case}
  283.            If TopleftXY[1] < 1 then
  284.               TopleftXY[1] := (80 - Fullwidth)  div 2;
  285.            If TopLeftXY[1] + Fullwidth < 80 then
  286.               X2 := TopleftXY[1] + Fullwidth
  287.            else
  288.            begin
  289.                X2 := 80;
  290.                TopLeftXY[1] := 80 - Fullwidth + 1;
  291.            end;
  292.        end; {with}
  293.    end; {Proc Determine_X_Dimensions}
  294.  
  295.    Procedure Determine_Y_Dimensions;
  296.    var
  297.       BoxLines,
  298.       TopicLines,
  299.       FullDepth  : integer;
  300.    begin
  301.        With MenuDef do
  302.        begin
  303.            TopicLines := TotalPicks div PicksPerLine;  {no of full rows of picks}
  304.            If TotalPicks mod PicksPerLine > 0 then     {+1 if partial row of picks}
  305.               TopicLines := succ(TopicLines);
  306.            Case BoxType of
  307.            0    : Boxlines := 0;
  308.            1..5 : BoxLines :=  2;     {box sides}
  309.            6..9: BoxLines :=  3;     {box sides and shadow}
  310.            end;
  311.            Heading_Lines := 0;
  312.            If length(Heading1) > 0 then
  313.               Heading_Lines := succ(Heading_Lines);
  314.            If length(Heading2) > 0 then
  315.               Heading_Lines := succ(Heading_Lines);
  316.            If Heading_Lines > 0 then                   {add a line for a gap}
  317.               Heading_Lines := succ(Heading_Lines);    {gap above topics}
  318.            If BoxType = 5 then
  319.               Heading_Lines := succ(Heading_Lines);
  320.            Fulldepth := BoxLines+TopicLines+Heading_Lines;
  321.            If Heading_Lines > 0 then
  322.              Fulldepth := succ(Fulldepth);  {+1 gap below topics if headings}
  323.            If FullDepth > DisplayLines then   {if it doesn't fit, drop off topics}
  324.            begin
  325.                If Heading_Lines > 0 then
  326.                   TotalPicks :=  (DisplayLines - BoxLines -Heading_Lines-1)*PicksPerLine
  327.                else
  328.                   TotalPicks :=  (DisplayLines - BoxLines - Heading_Lines)*PicksPerLine;
  329.                FullDepth := 25;
  330.            end;
  331.            If TopLeftXY[2] <= 0 then
  332.               TopLeftXY[2] := (DisplayLines - Fulldepth) div 2 +1;
  333.            If TopLeftXY[2] + Fulldepth - 1 <= DisplayLines then
  334.            begin
  335.                If BoxType > 4 then   {shadow}
  336.                   Y2 := TopleftXY[2] + (Fulldepth) - 2     {Mod 5.00a}
  337.                else
  338.                   Y2 := TopleftXY[2] + pred(Fulldepth);    {Mod 5.00a}
  339.            end
  340.            else
  341.            begin
  342.                If BoxType > 4 then   {shadow}
  343.                   Y2 := pred(DisplayLines)
  344.                else
  345.                   Y2 := DisplayLines;
  346.                TopLeftXY[2] := DisplayLines - Fulldepth {+ 1};   {WZ}
  347.            end;
  348.    end;   {do}
  349.    end; {Proc Determine_Y_Dimensions}
  350.  
  351.    begin                              {Get_Dimensions}
  352.        Validate_Prefix;
  353.        Add_Prefix;
  354.        Find_Longest_Topic;
  355.        Determine_MaxWidth;
  356.        Validate_PicksPerLine;
  357.        Adjust_Text_Width(TextWidth);
  358.        Determine_X_Dimensions;
  359.        Determine_Y_Dimensions;
  360.    end;   {proc GetDimensions}
  361.  
  362.    Procedure Write_Text(Item:integer;Highlight:boolean);
  363.    Var X,Y,A:integer;
  364.    begin
  365.        With MenuDEf do
  366.        begin
  367.            A := Item mod PicksPerLine;
  368.            Y := Item div PicksPerLine +TopleftXY[2] + ord(A <> 0);
  369.            Y := Y + Heading_lines - ord(Boxtype = 0);
  370.            If A = 0 then A := PicksPerLine;      {A is now the no of picks from left}
  371.            X := (A - 1)*(TextWidth + 1)+Margins+
  372.                 TopleftXY[1]+1 + ord(BoxType > 0);          {title width + 1 for a space}
  373.            If Highlight then
  374.            begin
  375.                WriteAt(X,Y,colors[1],colors[2],Topic[item]);
  376.                WriteAT(pred(X),Y,colors[5],colors[2],chr(16));  {write arrow head}
  377.            end
  378.            else
  379.            begin
  380.                WriteAT(X,Y,colors[3],colors[4],Topic[item]);
  381.                WriteAT(pred(X),Y,colors[3],colors[4],' ');       {remove arrow head}
  382.                If AddPrefix = 4 then                             {highlight the capital letter}
  383.                   WriteAT(Pred(X)+First_Capital_Pos(Topic[Item]),Y,
  384.                           colors[1],colors[4],
  385.                           First_Capital(Topic[Item]));
  386.            end;
  387.        end;  {do}
  388.    end;  {Proc Write_Text}
  389.  
  390.    Procedure CreateMenu;
  391.    var I : integer;
  392.    begin
  393.    with MenuDef do
  394.    begin
  395.     If Window then
  396.            MkWin(TopleftXY[1],TopLeftXY[2],X2,Y2,colors[3],colors[4],boxtype)
  397.     else
  398.     begin
  399.         ClearText(TopleftXY[1],TopLeftXY[2],X2,Y2,colors[3],colors[4]);
  400.         If (BoxType in [5..9]) and (TopleftXY[1] > 1) then      {draw a shadow}
  401.         begin
  402.             For I := TopleftXY[2]+1 to Y2+1 do
  403.                 WriteAt(pred(TopLeftXY[1]),I,colors[3],black,' ');
  404.             WriteAt(TopLeftXY[1],succ(Y2),colors[3],black,
  405.                 replicate(X2-succ(TopLeftXY[1]),' '));
  406.         end;
  407.     end;
  408.     Case Boxtype of
  409.     1..4: Box(TopLeftXY[1],TopLeftXY[2],X2,Y2,colors[5],colors[4],Boxtype);
  410.     5   : begin
  411.               WriteAT(TopleftXY[1],TopleftXY[2],colors[5],colors[4],
  412.                       replicate(succ(X2 - TopleftXY[1]),chr(223)));
  413.               WriteAT(TopleftXY[1],TopleftXY[2]+Heading_Lines-1,colors[5],colors[4],
  414.                       replicate(succ(X2 - TopleftXY[1]),chr(196)));
  415.           end;
  416.     6..9:Box(TopLeftXY[1],TopLeftXY[2],X2,Y2,colors[5],colors[4],Boxtype-5);
  417.     end; {case}
  418.  
  419.     If length(Heading1) > 0 then
  420.        WriteBetween(TopleftXY[1],X2,
  421.                     TopLeftXY[2]+ord(BoxType > 0),
  422.                     colors[1],colors[4],Heading1);
  423.     If length(Heading2) > 0 then
  424.        WriteBetween(TopleftXY[1],X2,
  425.                     TopLeftXY[2]+ord(BoxType > 0)+ord(Heading_Lines <> 2),
  426.                     colors[1],colors[4],Heading2);
  427.     For I := 1 to TotalPicks do
  428.         Write_Text(I,false);
  429.     Write_Text(Choice,True);       {Highlight Default}
  430.    end; {do}
  431.    end; {Proc CreateMenu}
  432.  
  433.    Procedure Process_Keystrokes;
  434.    var
  435.      Found,
  436.      Selected: Boolean;
  437.      ChT,
  438.      CHpk:char;
  439.      Oldchoice:integer;
  440.      I,
  441.      Ecode:integer;
  442.      ScanTop,ScanBot,Cx,Cy : byte;
  443.    begin
  444.        Selected := false;
  445.        Found := false;
  446.        FindCursor(Cx,Cy,ScanTop,ScanBot);
  447.        OffCursor;
  448.        With MenuDef do
  449.        begin
  450.        Repeat
  451.              Chpk := GetKey;
  452. {$IFNDEF VER40}
  453.              MenuDef.Hook(Chpk,Choice,Ecode);   {call the user hook}
  454. {$ELSE}
  455.              If M_UserHook <> Nil then
  456.                 Call_Hook(Chpk,Choice,Ecode);
  457. {$ENDIF}
  458.              Case upcase(CHpk) of
  459.              #208 : begin       {Cursor Down}
  460.                         Write_text(Choice,false);
  461.                         Choice := Choice + PicksPerLine;
  462.                         If Choice > TotalPicks then
  463.                            Choice := (Choice mod PicksPerLine) + 1;
  464.                         Write_Text(Choice,true);
  465.                     end;
  466.              #129 : If Choice + PicksPerLine  <= TotalPicks then  {Mouse Down}
  467.                     begin
  468.                         Write_text(Choice,false);
  469.                         Choice := Choice + PicksPerLine;
  470.                         Write_Text(Choice,true);
  471.                     end;
  472.              #200 : begin       {cursor up}
  473.                         Write_Text(Choice,false);
  474.                         Choice := Choice - PicksPerLine;
  475.                         If Choice < 1 then
  476.                         begin
  477.                            Choice := Choice + PicksPerline;
  478.                            Choice :=
  479.                              ((TotalPicks div PicksPerLine)*PicksPerLine)
  480.                              - PicksPerLine + 1 + Choice - 2;
  481.                            If Choice + PicksPerLine <= TotalPicks then
  482.                               Choice := Choice + PicksPerLine;   {phew!}
  483.                         end;
  484.                         Write_Text(Choice,true);
  485.                     end;
  486.              #128 : If Choice - PicksPerLine > 0 then   {Mouse up}
  487.                     begin
  488.                         Write_Text(Choice,false);
  489.                         Choice := Choice - PicksPerLine;
  490.                         Write_Text(Choice,true);
  491.                     end;
  492.              #203 : begin       {cursor left}
  493.                         Write_Text(Choice,False);
  494.                         Choice := pred(choice);
  495.                         If choice = 0 then Choice := TotalPicks;
  496.                         Write_Text(Choice,true);
  497.                     end;
  498.              #130 : If (pred(Choice) > 0)  {mouse left}
  499.                     and ( Choice mod PicksPerLine <> 1) then
  500.                     begin
  501.                         Write_Text(Choice,False);
  502.                         Choice := pred(choice);
  503.                         Write_Text(Choice,true);
  504.                     end;
  505.              ' ',
  506.              #205 : begin        {cursor right}
  507.                         Write_Text(Choice,false);
  508.                         Choice := succ(Choice);
  509.                         If choice > TotalPicks then Choice := 1;
  510.                         Write_Text(Choice,true);
  511.                     end;
  512.              #131 : If (succ(Choice) <= TotalPicks) {Mouse right}
  513.                     and ( Choice mod PicksPerLine <> 0) then
  514.                     begin
  515.                         Write_Text(Choice,false);
  516.                         Choice := succ(Choice);
  517.                         Write_Text(Choice,true);
  518.                     end;
  519.              #199 : begin         {home key}
  520.                         Write_Text(Choice,false);
  521.                         Choice := 1;
  522.                         Write_Text(Choice,true);
  523.                     end;
  524.              #207 : begin         {end key}
  525.                         Write_Text(Choice,false);
  526.                         Choice := TotalPicks;
  527.                         Write_Text(Choice,true);
  528.                     end;
  529.              #133,                 {Mouse enter}
  530.              #13  : begin          {enter key}
  531.                         Selected := true;
  532.                         Errorcode := 0;
  533.                     end;
  534.              #0   : begin
  535.                         Selected := true;
  536.                         ErrorCode := Ecode;
  537.                     end;
  538.              #132,                    {Mouse Esc}
  539.              #27  : If AllowEsc then  {Esc}
  540.                     begin
  541.                         Selected := true;
  542.                         ErrorCode := 1;
  543.                     end
  544.                     else
  545.                     begin
  546.                         Write_Text(Choice,false);
  547.                         Choice := TotalPicks;
  548.                         Write_Text(Choice,true);
  549.                     end;
  550.              #187..#196 : If Addprefix = 3 then   {F1 to F10}
  551.                           begin
  552.                               Oldchoice := Choice;
  553.                               Case Upcase(Chpk) of
  554.                               #187 : If TotalPicks >= 1  then choice := 1 else choice := 0;
  555.                               #188 : If TotalPicks >= 2  then choice := 2 else choice := 0;
  556.                               #189 : If TotalPicks >= 3  then choice := 3 else choice := 0;
  557.                               #190 : If TotalPicks >= 4  then choice := 4 else choice := 0;
  558.                               #191 : If TotalPicks >= 5  then choice := 5 else choice := 0;
  559.                               #192 : If TotalPicks >= 6  then choice := 6 else choice := 0;
  560.                               #193 : If TotalPicks >= 7  then choice := 7 else choice := 0;
  561.                               #194 : If TotalPicks >= 8  then choice := 8 else choice := 0;
  562.                               #195 : If TotalPicks >= 9  then choice := 9 else choice := 0;
  563.                               #196 : If TotalPicks >= 10 then choice := 10 else choice := 0;
  564.                               end;  {case}
  565.                               If Choice = 0 then
  566.                                  Choice := Oldchoice
  567.                               else
  568.                               begin
  569.                                   Write_Text(Oldchoice,false);
  570.                                   Write_Text(Choice,true);
  571.                                   Selected := true;
  572.                                   Errorcode := 0;
  573.                               end;
  574.                           end;
  575.              '0'..'9': If (AddPrefix in [1,3]) then   {Number or Function Prefix} {4.02}
  576.                        begin
  577.                            If (Str_to_int(CHpk) in [1..TotalPicks]) then
  578.                            begin
  579.                                Write_Text(Choice,false);
  580.                                Choice := Str_to_Int(CHpk);
  581.                                Write_Text(Choice,true);
  582.                                Selected := true;
  583.                                ErrorCode := 0;
  584.                            end;
  585.                        end;
  586.              'A'..'Z': If AddPrefix = 2 then
  587.                        begin
  588.                           If (pos(upcase(CHpk),Alphabet) in [1..TotalPicks]) then
  589.                           begin
  590.                               Write_Text(Choice,false);
  591.                               Choice := pos(upcase(CHpk),Alphabet);
  592.                               Write_Text(Choice,true);
  593.                               Selected := true;
  594.                               Errorcode := 0;
  595.                           end;
  596.                        end
  597.                        else
  598.                        begin
  599.                            If AddPrefix = 4 then
  600.                            begin
  601.                                Found := false;
  602.                                I := Choice;
  603.                                Repeat
  604.                                     If First_Capital(Topic[I]) = upcase(ChPk) then
  605.                                     begin
  606.                                         Found := true;
  607.                                         Write_Text(Choice,false);
  608.                                         Choice := I;
  609.                                         Write_Text(Choice,true);
  610.                                         Selected := true;
  611.                                         Errorcode := 0;
  612.                                     end
  613.                                     else
  614.                                         If I = TotalPicks then
  615.                                            I := 1
  616.                                         else
  617.                                            Inc(I);
  618.                                Until Found or (I = Choice);
  619.                            end;
  620.                         end;
  621.                     end;
  622.        Until Selected;
  623.        SizeCursor(ScanTop,ScanBot);
  624.        end; {do}
  625.   end; {proc Process_keystrokes}
  626.  
  627. begin
  628.    GetDimensions;
  629.    CreateMenu;
  630.    Horiz_Sensitivity := 2;  {two cursors left/right before mouse returns a keypress}
  631.    Process_Keystrokes;
  632.    If Window then RmWin;
  633. end;        {Main Procedure DisplayMenu}
  634.  
  635. begin
  636. end.
  637.